package lz.controls
{
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFieldType;
	import flash.text.TextFormat;
	
	import lz.controls.core.InvalidationType;
	import lz.controls.core.UIComponent;
	import lz.controls.events.ComponentEvent;
	/**
	 * Label 组件将显示一行或多行纯文本或 HTML 格式的文本，这些文本的对齐和大小格式可进行设置。 
	 * Label 组件没有边框并且无法获得焦点。
	 * 每个 Label 实例的实时预览反映在创作过程中对“属性”检查器或“组件”检查器中的参数所做的更改。 
	 * 由于 Label 组件没有边框，因此查看 Label 实例的实时预览的唯一方法就是设置其 text 属性。
	 * @author lake
	 * 
	 */
	public class Label extends UIComponent
	{
		/**
		 * 对 Label 组件的内部文本字段的引用。
		 */
		public var textField:TextField;
		/**
		 * 精确的宽度
		 */
		protected var actualWidth:Number;
		/**
		 * 精确的高度
		 */
		protected var actualHeight:Number;
		/**
		 * 默认标签
		 */
		protected var defaultLabel:String="Label";
		/**
		 * 保存的html格式文本
		 */
		protected var _savedHTML:String;
		/**
		 * 是否显示html格式文本
		 */
		protected var _html:Boolean=false;
		/**
		 * 默认样式
		 */
		private static var defaultStyles:Object={textFormat: null, embedFonts: false};
		/**
		 * 检索当前组件的默认样式映射。
		 */
		public static function getStyleDefinition():Object
		{
			return defaultStyles;
		}
		/**
		 * 创建新的 Label 组件实例。
		 */
		public function Label()
		{
			super();

			text=defaultLabel;
			actualWidth=_width;
			actualHeight=_height;
		}
		/**
		 * 获取或设置由 Label 组件显示的纯文本。
		 * 请注意，字符串中表示 HTML 标记的字符没有任何特殊含义，将与输入时的显示一样。
		 * 若要显示包含 HTML 标签的文本，请使用 htmlText 属性。 
		 * HTML 将替换任何使用 htmlText 属性设置的文本，text 属性将删除 HTML 文本中的 HTML 标签以返回其纯文本格式的内容。
		 * 如果在属性检查器中 text 属性已由默认值发生了变化，则其在属性检查器中将优先于 htmlText 属性。
		 * 默认值为 "Label"。
		 */
		public function get text():String
		{
			return textField.text;
		}
		public function set text(value:String):void
		{
			// Value is the same as what is already set.
			if (value == text)
			{
				return;
			}
			// Value in the PI is the default.
			if (componentInspectorSetting && value == defaultLabel)
			{
				return;
			}
			// Clear the HTML value, and redraw.
			_html=false;
			textField.text=value;
			/*var tw:Number = textField.textWidth + 5;
			var th:Number = textField.textHeight + 5;
			setSize(tw,th);*/
			if (textField.autoSize != TextFieldAutoSize.NONE)
			{
				invalidate(InvalidationType.SIZE);
			}
		}
		/**
		 * 获取或设置由 Label 组件显示的文本，包括表示该文本样式的 HTML 标签。 
		 * 可以使用 TextField 对象支持的 HTML 标签的子集在此属性中指定 HTML 文本。
		 * 如果在属性检查器中更改了 text 属性的默认值，此更改的值优先于属性检查器中 htmlText 属性字段中的任何值。
		 * 若要在属性检查器中使用 htmlText 属性，text 属性字段必须包含 Label 值（与显示的完全相同）。
		 * 使用 ActionScript 进行编码时，无需设置 text 属性值；默认值为 Label。
		 * 默认值为 ""。
		 */
		public function get htmlText():String
		{
			return textField.htmlText;
		}
		public function set htmlText(value:String):void
		{
			// Value is the same as what is already set.
			if (value == htmlText)
			{
				return;
			}
			// Nothing is set in the PI.
			if (componentInspectorSetting && value == "")
			{
				return;
			}
			// Remember the html for later.
			_html=true;
			_savedHTML=value;
			// Change the text, and possibly resize.
			textField.htmlText=value;
			if (textField.autoSize != TextFieldAutoSize.NONE)
			{
				invalidate(InvalidationType.SIZE);
			}
		}
		/**
		 * 获取或设置一个值，该值指示是否应从包含 HTML 文本的 Label 组件中删除额外空白，如空格和换行符。 
		 * true 值指示删除多余的空白；false 值指示保留多余的空白。
		 * condenseWhite 属性只影响使用 htmlText 属性（而非 text 属性）设置的文本。 
		 * 如果使用 text 属性设置文本，则忽略 condenseWhite 属性。
		 * 如果将 condenseWhite 属性设置为 true，则必须使用标准 HTML 命令（如 <br> 和 <p>）使文本字段中的文本换行。
		 * 默认值为 false。
		 */
		public function get condenseWhite():Boolean
		{
			return textField.condenseWhite;
		}
		public function set condenseWhite(value:Boolean):void
		{
			textField.condenseWhite=value;
			if (textField.autoSize != TextFieldAutoSize.NONE)
			{
				invalidate(InvalidationType.SIZE);
			}
		}
		/**
		 * 获取或设置一个值，指示文本是否可选。 
		 * true 值指示文本可选；false 值指示文本不可选。
		 * 可选的文本可由用户从 Label 组件进行复制。
		 * 默认值为 false。
		 */
		public function get selectable():Boolean
		{
			return textField.selectable;
		}
		public function set selectable(value:Boolean):void
		{
			textField.selectable=value;
		}
		/**
		 * 获取或设置一个值，指示文本字段是否支持自动换行。 
		 * true 值指示支持自动换行；false 值指示不支持自动换行。
		 * 默认值为 false。
		 */
		public function get wordWrap():Boolean
		{
			return textField.wordWrap;
		}
		public function set wordWrap(value:Boolean):void
		{
			textField.wordWrap=value;
			if (textField.autoSize != TextFieldAutoSize.NONE)
			{
				invalidate(InvalidationType.SIZE);
			}
		}
		/**
		 * 获取或设置一个字符串，指示如何调整标签大小和对齐标签以适合其 text 属性的值。 以下是有效值：
		 * TextFieldAutoSize.NONE：不调整标签大小或对齐标签来适合文本。
		 * TextFieldAutoSize.LEFT：调整标签右边和底边的大小以适合文本。不会调整左边和上边的大小。
		 * TextFieldAutoSize.CENTER：调整标签左边和右边的大小以适合文本。标签的水平中心锚定在它原始的水平中心位置。
		 * TextFieldAutoSize.RIGHT：调整标签左边和底边的大小以适合文本。不会调整上边和右边的大小。
		 * 默认值为 TextFieldAutoSize.NONE。
		 */
		public function get autoSize():String
		{
			return textField.autoSize;
		}
		public function set autoSize(value:String):void
		{
			textField.autoSize=value;
			invalidate(InvalidationType.SIZE);
		}
		/**
		 * 获取设置组件宽度
		 */
		override public function get width():Number
		{
			if (textField.autoSize != TextFieldAutoSize.NONE && !wordWrap)
			{
				return _width;
			}
			else
			{
				return actualWidth;
			}
		}
		override public function set width(value:Number):void
		{
			actualWidth=value;
			super.width=value;
		}
		/**
		 * 获取组件高度
		 */
		override public function get height():Number
		{
			if (textField.autoSize != TextFieldAutoSize.NONE && wordWrap)
			{
				return _height;
			}
			else
			{
				return actualHeight;
			}
		}
		/**
		 * 设置大小
		 */
		override public function setSize(width:Number, height:Number):void
		{
			actualWidth=width;
			actualHeight=height;
			super.setSize(width, height);
		}
		/**
		 * 配置UI
		 */
		override protected function configUI():void
		{
			super.configUI();

			textField=new TextField();
			addChild(textField);
			textField.type=TextFieldType.DYNAMIC;
			textField.selectable=false;
			textField.wordWrap=false;
		}
		/**
		 * 绘制组件
		 */
		override protected function draw():void
		{
			if (isInvalid(InvalidationType.STYLES, InvalidationType.STATE))
			{
				drawTextFormat();

				var embed:Object=getStyleValue('embedFonts');
				if (embed != null)
				{
					textField.embedFonts=embed;
				}

				if (textField.autoSize != TextFieldAutoSize.NONE)
				{
					invalidate(InvalidationType.SIZE, false);
				}
			}
			if (isInvalid(InvalidationType.SIZE))
			{
				drawLayout();
			}
			super.draw();
		}
		/**
		 * 绘制文本格式
		 */
		protected function drawTextFormat():void
		{
			var tf:TextFormat=getStyleValue("textFormat") as TextFormat;
			if (tf == null)
			{
				var uiStyles:Object=UIComponent.getStyleDefinition();
				tf=enabled ? uiStyles.defaultTextFormat as TextFormat : uiStyles.defaultDisabledTextFormat as TextFormat;
			}

			textField.defaultTextFormat=tf; // This removes HTML Styles...
			textField.setTextFormat(tf);

			// Set the HTML again to make sure that the html styles are preserved.
			if (_html && _savedHTML != null)
			{
				htmlText=_savedHTML;
			}
		}
		/**
		 * 绘制布局
		 */
		protected function drawLayout():void
		{
			var resized:Boolean=false;

			textField.width=width;
			textField.height=height;

			if (textField.autoSize != TextFieldAutoSize.NONE)
			{

				var txtW:Number=textField.width;
				var txtH:Number=textField.height;

				resized=(_width != txtW || _height != txtH);
				// set the properties directly, so we don't trigger a callLater:
				_width=txtW;
				_height=txtH;

				switch (textField.autoSize)
				{
					case TextFieldAutoSize.CENTER:
						textField.x=(actualWidth / 2) - (textField.width / 2);
						break;
					case TextFieldAutoSize.LEFT:
						textField.x=0;
						break;
					case TextFieldAutoSize.RIGHT:
						textField.x=-(textField.width - actualWidth);
						break;
				}
			}
			else
			{
				textField.width=actualWidth;
				textField.height=actualHeight;
				textField.x=0;
			}
			if (resized)
			{
				dispatchEvent(new ComponentEvent(ComponentEvent.RESIZE, true));
			}
		}
	}
}
